#include "widget.h"
#include "ui_widget.h"
#include <vector>
#include <QDebug>
#include <QTime>
#include <QTableView>
using std::vector;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget),video(0)
{
    ui->setupUi(this);
    IsShow = false;
    model = new QSqlQueryModel(this);
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this,SLOT(UpdatePic()));
    timer->start(100);  //每秒钟检测10帧
    ui->label->setScaledContents(true);
    ui->tips->setText("welcome");

    //创建级联分类器，并加载模型文件
    classifier = new cv::CascadeClassifier("/home/ljw/project/opencv-3.1.0/data/haarcascades/haarcascade_frontalface_alt.xml");
    bdf = new baiduFace("5pdFGPo8uYLGdllF4g28O7uw","tB2BPpwBRSnMZsqNiZ8bGNP3NwZ78ke4",this);
    connect(bdf,&baiduFace::isfound,this,&Widget::IsFoundFace);

    //设置组id
    group = "777";
    sound = new QSound("3.wav",this);

    //创建数据库,建表
    if(true == QSqlDatabase::contains("qt_sql_default_connection"))
    {
         db = QSqlDatabase::database("qt_sql_default_connection");
         qDebug() << "connection there";
    }
    else
    {
        db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("check-in.db");
        bool ok = db.open();
        if(ok)
        {
            qDebug() << "open db ok";
        }
        else
        {
            qDebug() << "db open error!" << db.lastError();
        }
    }

    //创建数据库并建表
    QSqlQuery sql_query;
    QString sql_create_table = "create table face_list (count int primary key,name varchar(30),id varchar(30),time varchar(30) default 0)";
    if(!db.tables().contains("face_list"))
    {
        sql_query.prepare(sql_create_table);
        bool exec_ok = sql_query.exec();
        if(true == exec_ok)
        {
            //数据库中数据
            sql_query.exec("insert into face_list(count,name,id) values(1,'hqd','001')");
            sql_query.exec("insert into face_list(count,name,id) values(2,'ljw','002')");
            sql_query.exec("insert into face_list(count,name,id) values(3,'jks','003')");
            qDebug() << "create table and initialize ok!";
        }
        else
        {
            qDebug() << "create table and initialize failed!" << sql_query.lastError();
        }
    }
}

void Widget::sleep(int msec)
{
    QTime reachtime = QTime::currentTime().addMSecs(msec);
    while(QTime::currentTime()< reachtime)
    {
        QCoreApplication::processEvents(QEventLoop::AllEvents,100);
    }
}

void Widget::DetectFace(cv::Mat& img)
{
    //累计连续检测成功次数，如果等于5次就认为检测到人脸并开始进行识别
    static int punch = 0;
    cv::Mat gray(img.size(), CV_8UC1);

    //灰度处理
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
    cv::equalizeHist(gray, gray);
    vector<cv::Rect> objects;

    //搜寻人脸
    classifier->detectMultiScale(gray, objects,1.5,5);

    //发送识别好的人脸图片
    /*if(objects.size())
    {
        cv::rectangle(img,objects[0],CV_RGB(255,0,0));
        cv::Mat roi(img,objects[0]);
        vector<uchar> buf;
        cv::imencode(".jpg",roi,buf);
        //因为百度云的人脸识别速率为2帧/s，所以加了延时
        sleep(500);
        bdf->search(QByteArray::fromRawData((char*)buf.data(),buf.size()),group);
    }*/

    if (objects.size())
    {
        punch++;
        cv::rectangle(img, objects[0], CV_RGB(255,0,0));  //仅检测一张脸
        if (punch == 10 && sound->isFinished()&& IsShow == false) //识别成功5次之后且上次提示音频播放完之后才会继续检测人脸
        {
            cv::Mat roi(img, objects[0]);
            //to do recognize faces
            vector<uchar> buf;
            cv::imencode(".jpg",roi,buf);//将检测到的人脸存入到内存中去
            bdf->search(QByteArray::fromRawData((char*)buf.data(),buf.size()),group);//发送内存中的人脸信息去与百度云人脸库中的人脸进行比较
        }
    }
    else
    {
        punch = 0;
    }
}

//符合时间间隔
bool Widget::FitInterval(QString _uid)
{
    QSqlQuery sql_query;
    QString id,chTime;
    QDateTime now = QDateTime::currentDateTime();
    QDateTime old;
    QString select_sql = "select * from face_list";
    sql_query.exec(select_sql);
    while(sql_query.next())
    {
        id = sql_query.value(2).toString();
        if( id == _uid )
        {
            chTime = sql_query.value(3).toString();
        }
    }

    if(chTime == "0")
    {
        return true;
    }
    qDebug()<<chTime;

    //计算时间间隔
    old = QDateTime::fromString(chTime,"yyyy/MM/dd-hh:mm:ss");
    uint now_time,old_time;
    now_time = now.toTime_t();
    old_time = old.toTime_t();
    //签到时间间隔一分钟
    if((now_time - old_time)/60 < 1)
    {
        return false;
    }
    return true;
}

//看某个人签到了几次(所有的签到次数)
int Widget::SignInEffTimes(QString _uid)
{
    //统计签到次数
    int cot = 0;
    QSqlQuery sql_query;
    QString fid;
    QString select_sql = "select * from face_list";
    if(sql_query.exec(select_sql))
    {
        while(sql_query.next())
        {
            fid = sql_query.value(2).toString();
            if(_uid == fid)
            {
                cot++;
            }
        }
    }
    return cot;
}

void Widget::IsFoundFace(bool yes)
{
    //更新提示框上的签到信息
    if(yes && FitInterval(bdf->userid()))
    {
        ui->tips->setText(bdf->userid() + " sign in successfully!");
        qDebug()<<SignInEffTimes(bdf->userid());
        sound->play("3.wav");
        UpdateDbInfo(bdf->userid());
        ui->tips->setText("welcome");
    }
    else
    {
        ui->tips->setText(bdf->userid() + " sign in failed " + "please wait a minute!");
        sleep(2000);
        ui->tips->setText("welcome");
    }
}

//更新数据库操作
void Widget::UpdateDbInfo(QString _uid)
{
    if(FitInterval(_uid))
    {
        QSqlQuery sql_query;
        QString select_sql = "select * from face_list";
        sql_query.exec(select_sql);
        QString id,name;
        //查询数据库找到符合id的人，记录其id和name
        while(sql_query.next())
        {
            id = sql_query.value(2).toString();
            name = sql_query.value(1).toString();
            if(id == _uid)
            {
                qDebug()<<"find this man";
                break;
            }
        }
        //找到数据库中当前最大的编号
        select_sql = "select * from face_list";
        sql_query.exec(select_sql);
        int maxcot;
        while(sql_query.next())
        {
            maxcot = sql_query.value(0).toInt();
        }
        qDebug()<<maxcot;
        maxcot++;
        //数据库中插入数据
        QString time =QDateTime::currentDateTime().toString("yyyy/MM/dd-hh:mm:ss");
        QString insert_sql = "insert into face_list(count,name,id,time) values(:maxcot,:name,:id,:time)";
        sql_query.prepare(insert_sql);
        sql_query.bindValue(":maxcot",maxcot);
        sql_query.bindValue(":id",id);
        sql_query.bindValue(":name",name);
        sql_query.bindValue(":time",time);
        bool exec_ok = sql_query.exec();
        if(true == exec_ok)
        {
            qDebug() << "insert data ok";
        }
        else
        {
            qDebug() << "insert table error" << sql_query.lastError();
        }
    }
}

//更新label上的画面
void Widget::UpdatePic()
{
    cv::Mat image;
    video >> image;  //采集一帧图像
    DetectFace(image);
    cv::cvtColor(image, image, CV_BGR2RGB);   //将OpenCV的Mat数据结构转换为QImage
    ui->label->setPixmap(QPixmap::fromImage(QImage(image.data, image.cols, image.rows, image.step, QImage::Format_RGB888)));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_infoBtn_clicked()
{
    IsShow = true;
    ui->stackedWidget->setCurrentWidget(ui->page_2);
    QString show = "select * from face_list where time > 0";
    model->setQuery(show);
    ui->tableView->setModel(model);
    ui->tableView->resizeColumnsToContents();
    ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
}

void Widget::on_pushButton_clicked()
{
    IsShow = false;
    ui->stackedWidget->setCurrentWidget(ui->page);
}
